<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>视频通话</title>
		<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0,viewport-fit=cover">
	</head>
	<script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
	<script src="js/RTCMultiConnection.js"></script>
	<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
	<script src="js/weui.min.js"></script>
	<script src="js/FileBufferReader.js"></script>
	<script src="js/CodecsHandler.js"></script>
	<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
	<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/3.9.0/vconsole.min.js"></script>
	<link rel="stylesheet" href="css/weui.css">
	<link rel="stylesheet" href="css/index.css">
	<body ontouchstart>
		<p id="bear"></p>
		<div id="app" class="w-100 h-100">
			<div v-if="isJoin" class="video_container">
				<div @click="switchScree(item)" v-for="item in videosList"
					:class="[item.isScreeFull||videosList.length==1 ?'max_scree':'min_scree']">
					<video-item v-bind:item="item" v-bind:key="item.id">
					</video-item>
				</div>
				<div class="msg_container">
					<div class="msg" ref="list">
						<div class="msg_item" v-for="(msg,index) in msgList" :key="index">
							<span class="span_msg">
								<span class="title">{{msg.extra.name}}:</span>
								<span>{{msg.data.msg}}</span>
							</span>
						</div>
					</div>

				</div>
			</div>
			<!-- v-else -->
			<div v-else class="w-100 h-100">
				<div v-for="item in videosList" class="max_scree">
					<video-item v-bind:item="item" v-bind:key="item.id">
					</video-item>
					<div class="infos">
						<div class="tips">
							正在等待对方接受邀请
						</div>
						<div class="hangUpBtn">
							<div @click="back"><img src="images/gd.png"><span>取消</span></div>
						</div>
					</div>
				</div>
			</div>
			<div class="footer_input" v-if="isJoin">
				<div>
					<p class="input-btn" @click="open1">说些什么吧...</p>
				</div>
				<div class="video-manage">
					<div @click="muteClick">
						<img src="images/km.png" v-if="muteFlag">
						<img src="images/bm.png" v-else>
						<span>静音</span>
					</div>
					<div @click="SwitchCamera"><img src="images/xz.png"><span>切换</span></div>
					<div @click="hangUp"><img src="images/gd.png"><span>挂断</span></div>
				</div>
			</div>


			<div id="textToast" :class="[content?'show':'hidden']" role="alert">
				<div class="weui-mask_transparent"></div>
				<div class="weui-toast weui-toast_text">
					<p class="weui-toast__content">{{content}}</p>
				</div>
			</div>

			<div class="fadeIn" v-if="dialog1" aria-role="dialog" aria-modal="true" aria-labelledby="js_dialog1_title">
				<div class="weui-mask" @click="close"></div>
				<div class="weui-half-screen-dialog">
					<div class="weui-half-screen-dialog__bd" style="padding-top:15px;height:50px;">
						<div class="text-menu">
							<div class="text-menu-input">
								<textarea :autofocus="true" v-model="msgValue" placeholder="说的什么吧..."></textarea>
							</div>
							<div class="text-menu-btn" @click="send(msgValue)">
								<button type="button">发送</button>
							</div>
						</div>
					</div>
				</div>
			</div>

		</div>
	</body>
	<script type="text/javascript">
		// init vConsole
		// var vConsole = new VConsole();
		console.log('vConsole初始化');
		Vue.prototype.$weui = weui;
		Vue.component('videoItem', {
			props: ['item'],
			template: '<video width="100%" ref="video"  autoplay="autoplay" height="100%" :srcObject.prop="item.srcObject" :muted="item.muted" :id="item.id"></video>'
		})
		console.log(RTCMultiConnection)
		// import Vue from 'Vue'
		let connection = new RTCMultiConnection()
		var vm = new Vue({
			el: '#app',
			data() {
				return {
					localUserid: '',
					msgList: [],
					isJoin: false,
					videosList: [],
					msgValue: '',
					content: '',
					dialog1: false,
					muteFlag: false,
					CameraDirection: 'user',
					remoteInfo: {},
					stream: null
				}
			},
			mounted() {
				window.onbeforeunload = () => //author: meizz
					{
						var n = window.event.screenX - window.screenLeft;
						var b = n > document.documentElement.scrollWidth - 20;
						if (b && window.event.clientY < 0 || window.event.altKey) {
							this.hangUp()
						} else {
							this.hangUp()
						}

					}
				connection.socketURL = 'https://yzs.yzs100.cn:9989/'
				connection.enableFileSharing = true; // by default, it is "false".
				connection.socketMessageEvent = 'video-conference'
				connection.language = 'zh'
				connection.enableLogs = true;
				connection.closeBeforeUnload = false;
				connection.maxParticipantsAllowed = 2;
				connection.autoCloseEntireSession = false;
				connection.setCustomSocketEvent('custom-message');
				connection.userid = this.GetRequest('uid')
				connection.extra.name = this.GetRequest('uname')
				connection.extra.userid = this.GetRequest('uid')
				connection.socketOptions = {
					transports: ['websocket', 'xhr-polling', 'jsonp-polling'],
					'force new connection': false, // For SocketIO version < 1.0
					'forceNew': false, // For SocketIO version >= 1.0
				}
				connection.session = {
					audio: true,
					video: true,
					data: true
				}
				connection.iceServers = [
					's1.taraba.net'
				]
				connection.sdpConstraints.mandatory = {
					OfferToReceiveAudio: true,
					OfferToReceiveVideo: true
				}

				connection.sdpConstraints.optional = [{
					VoiceActivityDetection: true
				}]
				connection.autoCreateMediaElement = false;
				connection.onerror = e => {
					console.error('onerror', e);
				}
				connection.onSocketError = e => {
					console.error('onSocketError', e);
				}
				connection.onNumberOfBroadcastViewersUpdated = e => {
					console.log(e);
				}
				connection.connectSocket((socket) => {
					socket.on('custom-message', (event) => {
						console.log('获取自定义事件:', event);
						if (event.type == 'Refuse') {
							this.showToast("对方已拒绝")
							wx.miniProgram.navigateBack({
								delta: 1
							});
						} else if (event.type == 'hangUp' && event.userid != this.localUserid) {
							wx.miniProgram.postMessage({ data: {msg: 'remoteDisconnect'} })
							setTimeout(()=>{
								weui.alert('对方已挂断', function() {
									connection.attachStreams.forEach((localStream) => {
										localStream.stop();
									});
									wx.miniProgram.navigateBack({
										delta: 1
									});
								}, {
									title: '提 示'
								});
							},500)
						}

					});
				});
				connection.onmessage = (e) => {
					console.info('onmessage', e);
					if (e.data.type == 'call') {
						connection.join(e.data.userid)
					} else {
						this.msgList.push(e)
						this.scrollBottom()
					}

				};
				connection.autoCreateMediaElement = false;
				connection.onstream = (event) => {
					console.log('新增流变动', event, this.videosList);
					let videosList = []
					const allStream = connection.streamEvents.selectAll()
					allStream.forEach((stream, index) => {
						if (stream.type === 'local') {
							this.stream = stream.stream;
							this.localUserid = stream.userid
						} else {
							this.remoteInfo = stream
							this.isJoin = true
						}
						videosList.push({
							id: stream.streamid,
							type: stream.type,
							srcObject: stream.stream,
							muted: stream.type === 'local',
							isScreeFull: stream.type === 'remote',
							userid: stream.userid,
							isVideo: true,
							isAudio: true
						})
					})
					this.videosList = videosList
					// this.$nextTick(() => {
					// 	console.log(document.getElementsByTagName('video'));
					// 	this.videosList.forEach((e, i) => {
					// 		try{
					// 			console.log(document.getElementsByTagName('video')[i]);
					// 			document.getElementsByTagName('video')[i].play();
					// 		}catch(e){
					// 			console.log(e);
					// 		}
					// 	})
					// })
				};

				connection.onstreamended = (event) => {
					console.log('卸载流变动', event, this.videosList);
				};

				connection.onmute = e => {
					if (e.type == 'local') {
						if (e.isAudioMuted) {
							this.showToast("麦克风已关闭")
							this.muteFlag = false
						} else {
							this.showToast("操作失败")
						}
					} else {
						if (e.isAudioMuted) {
							this.showToast("对方已关闭麦克风")
						}
					}

				}
				connection.onunmute = e => {
					if (e.type == 'local') {
						if (!e.isAudioMuted) {
							this.showToast("麦克风已打开")
							this.muteFlag = true
						} else {
							this.showToast("操作失败")
						}
					} else {
						if (!e.isAudioMuted) {
							this.showToast("对方已开启麦克风")
						}
					}

				}
				this.$nextTick(() => {
					setTimeout(() => {
						this.call()
					}, 0)
				})
			},
			methods: {
				disconnectWith() {
					console.log(`与${this.remoteInfo.userid}断开连接`, this.remoteInfo.userid);

					return new Promise((resolve, reject) => {
						if (!this.remoteInfo.userid) {
							reject()
							return
						}
						connection.attachStreams.forEach((localStream) => {
							localStream.stop();
						});
						connection.disconnectWith(this.remoteInfo.userid, () => {
							connection.connectSocket((socket) => {
								socket.emit('custom-message', {
									type: 'hangUp',
									userid: this.localUserid,
									event:'manualDisconnect'
								});
							});
							setTimeout(() => {
								resolve()
							}, 1000)
						});
					})
				},
				hangUp() {
					const {
						userid
					} = this.remoteInfo
					connection.getExtraData(userid, remoteInfo => {
						weui.confirm(`此操作将与${remoteInfo.username}断开连接, 是否继续?`, () => {
							this.disconnectWith().then(() => {
								wx.miniProgram.navigateBack({
									delta: 1
								});
							}).catch(() => {
								wx.miniProgram.navigateBack({
									delta: 1
								});
							})
						}, function() {
							console.log('no');
						}, {
							title: '提 示'
						});
					})
				},
				back(){
					wx.miniProgram.navigateBack({
						delta: 1
					});
				},
				SwitchCamera() {
					this.CameraDirection = this.CameraDirection == 'user' ? 'environment' : 'user'
					var options = {
						localMediaConstraints: {
							audio: true,
							video: {
								facingMode: this.CameraDirection
							}
						},
						onGettingLocalMedia: (stream) => {
							this.videosList.forEach(v => {
								if (v.type == 'local') {
									this.$set(v, 'srcObject', stream)
									connection.replaceTrack(stream);
								}
							})
						},
						onLocalMediaError: function(error) {}
					};
					connection.getUserMediaHandler(options);
				},
				// 静音
				muteClick() {
					if (!this.muteFlag) {
						this.stream.mute('audio')
						this.muteFlag = true
					} else {
						this.stream.unmute('audio')
						this.muteFlag = false
					}
				},
				// 关闭输入框
				close() {
					this.dialog1 = false
				},
				//打开输入框
				open1() {
					this.dialog1 = true
				},
				GetRequest(value) {
					//url例子：www.bicycle.com?id="123456"&Name="bicycle"；  
					var url = decodeURI(location.search); //?id="123456"&Name="bicycle";
					var object = {};
					if (url.indexOf("?") != -1) //url中存在问号，也就说有参数。  
					{
						var str = url.substr(1); //得到?后面的字符串
						var strs = str.split("&"); //将得到的参数分隔成数组[id="123456",Name="bicycle"];
						for (var i = 0; i < strs.length; i++) {
							object[strs[i].split("=")[0]] = strs[i].split("=")[1]
						}
					}
					return object[value];
				},
				showToast(content = '', duration = 1000) {
					this.content = content;
					setTimeout(() => {
						this.content = '';
					}, duration)
				},
				call() {
					const roomId = this.GetRequest('roomid')
					connection.checkPresence(roomId, callback => {
						if (callback) {
							connection.join(roomId, e => {
								if (!e) {
									this.showToast("对方忙！")
								}
							});
						} else {
							this.showToast("对方不在线！")
							wx.miniProgram.navigateBack({
								delta: 1
							});
						}
					})
				},
				switchScree({
					isScreeFull
				}) {
					console.log(isScreeFull);
					if (isScreeFull) return;
					this.videosList.forEach(item => {
						this.$set(item, 'isScreeFull', !item.isScreeFull)
					})
				},
				send(value) {
					if (value) {
						const content = {
							msg: value,
							time: new Date().getTime(),
							type: 'msg'
						}
						connection.send(content);
						this.msgList.push({
							data: content,
							extra: {
								name: this.GetRequest('uname')
							},
							userid: this.localUserid
						})
						this.msgValue = ''
					}
					this.scrollBottom()
				},
				scrollBottom() {
					this.$nextTick(() => {
						this.$refs['list'].scrollTop = 99999999999;
					})
				}
			}
		})
	</script>
</html>
